package com.solr.web.service.search.impl;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.solr.web.dao.Search_SINFODao;
import com.solr.web.model.base.ResultModel;
import com.solr.web.model.entity.search.SearchEntity;
import com.solr.web.model.entity.search.Search_SINFOEntity;
import com.solr.web.model.vo.search.SearchVo;
import com.solr.web.model.vo.search.Search_SINFOVo;
import com.solr.web.service.search.SearchService;

@Service
public class SearchServiceImpl implements SearchService {
	
	@Autowired
	private Search_SINFODao search_SINFODao;
	
	@Autowired
	private SolrServer solrServer;
	
	@Value("${jdbc.url}")
	private String JDBC_URL;
	
	@Value("${jdbc.username}")
	private String JDBC_USERNAME;
	
	@Value("${jdbc.password}")
	private String JDBC_PASSWORD;
	
	 /**
     * 全量导入索引库
     * @return
     */
	@Override
	public ResultModel importAll() {
		ResultModel result = new ResultModel();
		
        Connection conn = null;
        
        //String url = "jdbc:mysql://localhost:3306/cia?user=root&password=123456&useUnicode=true&characterEncoding=UTF8";
        
        try {
            // 使用MySQL的驱动
            Class.forName("com.mysql.jdbc.Driver");// 动态加载mysql驱动

            System.out.println("成功加载MySQL驱动程序");
            // 一个Connection代表一个数据库连接
            conn = DriverManager.getConnection(JDBC_URL,JDBC_USERNAME,JDBC_PASSWORD);

            String sql_count="select count(*) from t_news_zw";
            PreparedStatement pstmCount = conn.prepareStatement(sql_count);
			ResultSet rsCount = pstmCount.executeQuery(sql_count);
			rsCount.next();
			int totalCount=rsCount.getInt(1);
            System.out.println("============totalCount==="+totalCount);
            
            int pageSize = 150000;
            
            //if(totalCount> pageSize){
				  int max=totalCount%pageSize==0 ? totalCount/pageSize : totalCount/pageSize+1;
				  
				  SolrInputDocument document;
				  SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				  for(int i=0;i<max;i++){
					  	List<SolrInputDocument>	docs = new ArrayList<>();
					  //conn = null;
					  
				        // 使用MySQL的驱动
			            //Class.forName("com.mysql.jdbc.Driver");// 动态加载mysql驱动

			           // System.out.println("成功加载MySQL驱动程序");
			            // 一个Connection代表一个数据库连接
			           // conn = DriverManager.getConnection(url);
			            
					  
						  //String sql_data="select a.id,a.keyword,a.title,a.href,a.publishtime,a.servicetype,b.area from t_news_zw a, t_news_keyword_area_map b where a.keyword=b.keyword limit "+ i*pageSize + " , "+pageSize;
						  String sql_data="select a.id,a.keyword,a.title,a.href,a.rate,a.publishtime,a.servicetype,b.area from t_news_zw a LEFT JOIN (SELECT distinct keyword,area FROM t_news_keyword_area_map) b on a.keyword=b.keyword limit "+ i*pageSize + " , "+pageSize;
						  System.out.println("==================="+sql_data);
						 
						  //conn.setAutoCommit(false); 
						  PreparedStatement pstm = conn.prepareStatement(sql_data);
						  
						  // Statement里面带有很多方法，比如executeUpdate可以实现插入，更新和删除等
						  // executeQuery会返回结果的集合，否则返回空值
						  ResultSet rs = pstm.executeQuery();
						  
						  while (rs.next()) {
							  document = new SolrInputDocument();
							  document.addField("id", rs.getLong("id"));
							  //document.addField("target", rs.getString("target"));
							  String keyword = rs.getString("keyword");
							  if (keyword != null && !"".equals(keyword)) {
								  document.addField("keyword", keyword);
							  }else{
								  document.addField("keyword", "");
							  }
							  /*document.addField("author", rs.getString("author"));
							  document.addField("time", rs.getString("time"));*/
							  String title = rs.getString("title");
							  if (title != null && !"".equals(title)) {
								  document.addField("title", title);
							  }else{
								  document.addField("title", "");
							  }
							  //document.addField("summary", rs.getString("summary"));
							  String href = rs.getString("href");
							  if (href != null && !"".equals(href)) {
								  document.addField("href", href);
							  }else{
								  document.addField("href","");
							  }
							  
							  document.addField("rate", rs.getDouble("rate"));
							  //document.addField("content", rs.getString("content"));
							  //document.addField("createTime", rs.getDate("createTime"));
							  //document.addField("publishtime", rs.getDate("publishtime"));
							  Timestamp timestamp = rs.getTimestamp("publishtime");
							  //System.out.println("timestamp-----------------------"+timestamp);
							  if (timestamp != null) {
								  String dateString = formatter.format(timestamp);
								  document.addField("publishtime", dateString);
							  }else {
								  document.addField("publishtime", "");
							  }
							  
							  Integer servicetype = rs.getInt("servicetype");
							  if (servicetype != null) {
								  document.addField("servicetype", servicetype);
							  }
							  //document.addField("industry", rs.getString("industry"));
							/*  document.addField("isornosend", rs.getInt("isornosend"));
							  document.addField("isornosend_gushou", rs.getInt("isornosend_gushou"));
							  document.addField("adjust_bond_rate", rs.getDouble("adjust_bond_rate"));
							  document.addField("adjust_bond_man", rs.getString("adjust_bond_man"));
							  document.addField("code", rs.getString("code"));
							  document.addField("time_stamp", rs.getDate("time_stamp"));*/
							  String area = rs.getString("area");
							  if (area != null && !"".equals(area)) {
								  document.addField("area", area);
							  }else{
								  document.addField("area","");
							  }
							  //document.addField("pinyin", pinyin4jUtils.converterToSpell(rs.getString("title")));
							  //document.addField("py", pinyin4jUtils.converterToFirstSpell(rs.getString("title")));
							  docs.add(document);
						  }
						  
						  
						  // 调用SolrServer的api方法将数据导入到索引库
						  solrServer.add(docs);
						  // 提交
						  solrServer.commit();
						  if (max%10==0) {
							  Thread.sleep(1000);
							
						}
				  }
				  
        } catch (Exception e) {
            e.printStackTrace();
            try {
				conn.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
        }
		return result;
	}
	
	/**

     * 增量导入索引库

     * @return

     */
	public ResultModel importWhere(String dateString){
		ResultModel result = new ResultModel();
        Connection conn = null;
        try {
            // 使用MySQL的驱动
            Class.forName("com.mysql.jdbc.Driver");// 动态加载mysql驱动

            System.out.println("成功加载MySQL驱动程序");
            // 一个Connection代表一个数据库连接

            conn = DriverManager.getConnection(JDBC_URL,JDBC_USERNAME,JDBC_PASSWORD);
            
            String sql_count="select count(*) from t_news_zw where createTime >= '"+dateString+"'";
            PreparedStatement pstmCount = conn.prepareStatement(sql_count);
			ResultSet rsCount = pstmCount.executeQuery(sql_count);
			rsCount.next();
			int totalCount=rsCount.getInt(1);
			System.out.println(sql_count);
            System.out.println("============totalCount==="+totalCount);
            
            int pageSize = 5000;
            
            int max=totalCount%pageSize==0 ? totalCount/pageSize : totalCount/pageSize+1;
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            
            SolrInputDocument document;
            for(int i=0;i<max;i++){
	            //String sql = "select a.id,a.keyword,a.title,a.href,a.publishtime,a.servicetype,b.area from t_news_zw a left join t_news_keyword_area_map b on a.keyword=b.keyword where a.publishtime >= '"+dateString+"' limit "+ i*pageSize + " , "+pageSize;
	            String sql = "select a.id,a.keyword,a.title,a.href,a.rate,a.publishtime,a.servicetype,b.area from t_news_zw a LEFT JOIN (SELECT distinct keyword,area FROM t_news_keyword_area_map) b on a.keyword=b.keyword where a.createTime >= '"+dateString+"' limit "+ i*pageSize + " , "+pageSize;
	            System.out.println("==================="+sql);
	            PreparedStatement pstm = conn.prepareStatement(sql);
	                
	            // Statement里面带有很多方法，比如executeUpdate可以实现插入，更新和删除等
	            // executeQuery会返回结果的集合，否则返回空值
	            ResultSet rs = pstm.executeQuery();
	                
	             List<SolrInputDocument> docs = new ArrayList<>();
				 
				 while (rs.next()) {
	            	 document = new SolrInputDocument();
					
	            	 document.addField("id", rs.getLong("id"));
	            	 
	            	 String keyword = rs.getString("keyword");
					  if (keyword != null && !"".equals(keyword)) {
						  document.addField("keyword", keyword);
					  }else{
						  document.addField("keyword", "");
					  }
					 
					 String title = rs.getString("title");
					  if (title != null && !"".equals(title)) {
						  document.addField("title", title);
					  }else{
						  document.addField("title", "");
					  }
					 
					 String href = rs.getString("href");
					  if (href != null && !"".equals(href)) {
						  document.addField("href", href);
					  }else{
						  document.addField("href","");
					  }
					 
					 document.addField("rate", rs.getDouble("rate"));
					  
					 Timestamp timestamp = rs.getTimestamp("publishtime");
					  if (timestamp != null) {
						  String date = formatter.format(timestamp);
						  document.addField("publishtime", date);
					  }else {
						  document.addField("publishtime", "");
					  }
					  
					  Integer servicetype = rs.getInt("servicetype");
					  if (servicetype != null) {
						  document.addField("servicetype", servicetype);
					  }
					  
					  String area = rs.getString("area");
					  if (area != null && !"".equals(area)) {
						  document.addField("area", area);
					  }else{
						  document.addField("area","");
					  }
					 
					 docs.add(document);
				}
				 
				 // 调用SolrServer的api方法将数据导入到索引库
				 solrServer.add(docs);
				 // 提交
				 solrServer.commit();
            }
                
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
        }
		return result;

    }
	

	 /**
     * 搜索
     * @return
     */
	@Override
	public Map<String, Object> search(String q, Integer page,String fq,String fq_rate) throws Exception {
		ModifiableSolrParams params = new ModifiableSolrParams();
		//查询对象
		SolrQuery query = new SolrQuery();
		
		StringBuffer sb = new StringBuffer();
		//设置查询关键字
		if (StringUtils.isNotEmpty(q)) {
			if (q.indexOf(" ")!=-1) {
				String[] strings = q.split(" ");
				for (int i = 0; i < strings.length; i++) {
					q='"'+strings[i]+'"';
					sb.append(q+" ");
				}
				query.setQuery(sb.toString());
			}else {
				query.setQuery('"'+q+'"');
			}
		}else {
			query.setQuery("*:*");
		}
		
		//设置分页
		if (page==null) {
			page=1;
		}
		
		query.setStart((page - 1)*15);
		query.setRows(15);
		
		//设置默认域
		query.set("df", "title");
		
		query.set("qt", "/select");		
		query.set("wt", "json");
		query.set("sort", "publishtime desc");
		query.addFilterQuery(fq);
		
		if (fq_rate!="" && fq_rate!=null && fq_rate.equals("1")) {
			fq_rate = "rate:[1 TO *]";
			query.addFilterQuery(fq_rate);
			
		}else if (fq_rate!="" && fq_rate!=null && fq_rate.equals("-1")) {
			fq_rate = "rate:[* TO -1]";
			query.addFilterQuery(fq_rate);
			
		}else if (fq_rate!="" && fq_rate!=null && fq_rate.equals("0")) {
			fq_rate = "rate:0";
			query.addFilterQuery(fq_rate);
			
		}
		params.add(query);
		
		//设置高亮
		/*query.setHighlight(true);
		query.addHighlightField("title");
		query.setHighlightSimplePre("<font style='color:red'>");
		query.setHighlightSimplePost("</font>");*/
		
		//搜索
		QueryResponse response = solrServer.query(params);
		SolrDocumentList results = response.getResults();
		
		//获取记录总数
		long totalRecords = results.getNumFound();
		
		//获取高亮信息
		//Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
		
		List<SearchVo> searchVoList = new ArrayList<>();
		SearchVo searchVo;
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		for (SolrDocument solrDocument : results) {
			searchVo = new SearchVo();
			searchVo.setId(Long.parseLong(solrDocument.get("id").toString()));
			//System.out.println("id::::::"+solrDocument.get("id").toString());
			
			//对搜索结果进行高亮处理
			//List<String> list = highlighting.get(solrDocument.get("id")).get("title");
			//System.out.println("title::::::"+list.get(0));
			//if (list != null && list.size()>0) {
			//	searchVo.setTitle(list.get(0));
			//}else {
				searchVo.setTitle(solrDocument.get("title").toString());
			//}
			searchVo.setKeyword(solrDocument.get("keyword").toString());
			searchVo.setHref(solrDocument.get("href").toString());
			searchVo.setRate(Double.parseDouble(solrDocument.get("rate").toString()));
			
			//String dateString = formatter.format(solrDocument.get("publishtime"));
			searchVo.setPublishtime(solrDocument.get("publishtime").toString());
			
			if (solrDocument.get("servicetype")!=null) {
				searchVo.setServicetype(Integer.parseInt(solrDocument.get("servicetype").toString()));
			}
			
			if (solrDocument.get("area")!=null) {
				searchVo.setArea(solrDocument.get("area").toString());
				
			}
			
			searchVoList.add(searchVo);
		}
		
		//得到totalPages（总页数）、searchVoList（搜素结果）、totalRecords（总记录数）
		Map<String,Object> map = new HashMap<>();
		
		map.put("totalRecords", totalRecords);
		
		//计算totalPages
		int totalPages =(int) (totalRecords / 15);
		if (totalRecords % 15 >0) {
			totalPages++;
		}
		
		map.put("totalPages", totalPages);
		
		map.put("searchVoList", searchVoList);
		
		return map;
	}
	

	private Search_SINFOVo entity2vo(Search_SINFOEntity search_SINFOEntity){
     	//TODO 此处需要将entity转换成VO
     	if(search_SINFOEntity == null){
     		return null;
     	}
     	Search_SINFOVo search_SINFOVo = new Search_SINFOVo();
     	BeanUtils.copyProperties(search_SINFOEntity, search_SINFOVo);
     	return search_SINFOVo;
     }
     
     private SearchEntity vo2entity(SearchVo searchVo){
     	//TODO 此处需要将VO转换成entity
     	if(searchVo == null){
     		return null;
     	}
     	SearchEntity searchEntity = new SearchEntity();
     	BeanUtils.copyProperties(searchVo, searchEntity);
     	return searchEntity;
     }

     /**
      * 根据股票Wind代码查股票名称
      */
	@Override
	public Search_SINFOVo getNameFromWindCode(String windcode) {
		return this.entity2vo(search_SINFODao.getNameFromWindCode(windcode));
	}

	/**
     * 根据股票交易代码查股票名称
     */
	@Override
	public Search_SINFOVo getNameFromCode(String code) {
		return this.entity2vo(search_SINFODao.getNameFromCode(code));
	}
	
	/**
     * 根据股票拼音简写查股票名称
     */
	@Override
	public Search_SINFOVo getNameFromPinYin(String pinyin) {
		return this.entity2vo(search_SINFODao.getNameFromPinYin(pinyin));
	}


	
}